[아두이노 강좌] 23. Interrupt(인터럽트) (3)

您所在的位置:网站首页 interrupt 3 [아두이노 강좌] 23. Interrupt(인터럽트) (3)

[아두이노 강좌] 23. Interrupt(인터럽트) (3)

2024-05-29 14:37| 来源: 网络整理| 查看: 265

>> *참고1 : 채터링(Chattering)에 대하여

지난 시간에 인터럽트를 사용한 예제 소스 또는 스위치의 상태를 저장하는 bSwOn 변수를 사용한 예제 소스를 실행했을 때 한 번에 잘 안되는 경우가 있었다. 스위치를 눌렀을 때 마치 여러 번 누른 듯 LED가 깜빡이는 현상.

 

스위치의 채터링(Chattering) 현상 때문이다. 채터링 현상에 대해 우리의 네이버는 다음과 같이 설명했다.

  

  IT용어사전 | 채터링

 

 전자 회로 내의 스위치나 계전기의 접점이 붙거나 떨어질 때 기계적인 진동에 의해 실제로는 매우 짧은 시간 안에 접점이 붙었다가 떨어지는 것을 반복하는 현상. 이는 회로에 나쁜 영향을 끼치므로 제거해야 한다.

 

 [네이버 지식백과] 채터링 [chattering] (용어해설)

 

나쁜 영향을 끼치니까 제거해야 한대. ㅠㅠ 나쁜 채터링.

 

채터링 현상을 그림으로 나타내면 다음과 같다.

 

스위치가 눌리는 순간에 신호가 바로 LOW로 떨어지는 것이 아니라 약간의 진동을 가지게 되는데, 이를 채터링 현상이라고 하며, 이 현상으로 인해 FALLING 모드로 설정된 인터럽트가 연속해서 발생하게 되는 것이다.

 

채터링 현상을 제거하기 위한 방법으로는 HW로 제거하는 방법과 SW로 제거하는 방법이 있는데, HW는 난 잘 모르니까 넘어가고, SW로 제거하는 가장 대표적인 방법은 시간을 체크해서 일정 시간 이상 신호를 유지하는 경우에만 유효한 신호로 인정하는 방법이다.

 

어떻게?? 

 

제일 쉬운 방법은 delay()를 사용하는 방법. 하지만 그리 추천하지 않는 이유는 인터럽트 함수 안에서 딜레이 구문을 사용하는 것은 좋은 방법이 아니기 때문이다. 게다가 아두이노 홈페이지의 attachInterrupt() 함수를 설명하는 부분에서는 ISR(인터럽트 처리 함수) 안에서 delay() 함수나 millis() 함수를 사용하지 말라고 명시되어 있다. delay() 함수나 millis() 함수 역시 타이머 인터럽트를 사용하는 함수이고, 하나의 ISR 구문이 처리 중일 때는 다른 인터럽트가 발생해도 처리되지 않기 때문에 delay() 함수를 사용하게 되면 영원히 멈춰버리는 현상이 나타날 수도... 헐.

 

그래서 어쩌란 말이냐!!

 

delay() 함수는 사용할 수 없지만, delayMicroseconds() 함수는 사용할 수 있다는 사실!! ㅋㅋㅋㅋ

 

 

delayMicroseconds() 함수는 타이머를 사용하지 않는다. 그래서 ISR 안에서도 사용할 수 있다. 대신 delayMicroseconds() 함수를 사용하는 만큼 ISR 구문의 처리가 길어져 다른 인터럽트(예를 들면 시리얼이라던지)가 처리될 수 없기 때문에 좋지 않은 코드인 것은 마찬가지지만 우린 단지 LED를 켜고 끌 뿐이니까. 간단한 코드에서는 사용해도 돼! 괜찮아!

 interruptTest04.ino

 int ledPin = 13;

 int swPin = 2;

 boolean bLedOn = false;

 

 void setup() {

   pinMode(ledPin, OUTPUT);

   pinMode(swPin, INPUT_PULLUP);

   attachInterrupt(0, swInterrupt, FALLING);

 

   digitalWrite(ledPin, LOW);

 }

 

 void loop() {

   delay(1000);

 }

 

 void swInterrupt() {

 delayMicroseconds(2000);

 if(digitalRead(swPin) != LOW) return ;

 

   if(bLedOn == false) {

     digitalWrite(ledPin, HIGH);

     bLedOn = true;

   } else {

     digitalWrite(ledPin, LOW);

     bLedOn = false;

   }

 }

 

swInterrupt() 함수 안에 2000 마이크로초(=2 밀리초) 만큼의 딜레이를 주고 핀의 상태를 읽어서 LOW를 유지하고 있지 않다면 LED 구문을 처리하기 전 함수를 종료시킨다. 실행해보면 잘 동작하는 것을 확인할 수 있다.

 

딜레이 시간은 스위치마다 조금씩 다를 수 있으니 조금씩 늘려가면서 알맞은 시간을 찾으면 된다.

 

채터링 안녕.

 

 

다시 한 번 말하지만, 인터럽트 처리 함수 안에서 딜레이를 사용하는 것은 좋은 소스가 아니다. 다른 인터럽트가 처리될 수 없기 때문이다. 그래서 아두이노에서는 "Debounce"라는 예제로 채터링 방지 예제를 제공하고 있다. 스케치 툴의 "파일→예제→02.Digital→Debounce"를 열어보면 어떻게 사용하는 지 알 수 있을 것이다. 

 



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3